/* 
 * Copyright (c) 2016, QUANRONG E-COMMDERCE LTD. All rights reserved.
 */
package com.cory.utils.security;

import java.security.GeneralSecurityException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.DSAPrivateKey;
import java.security.interfaces.DSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
import com.cory.utils.lang.ExceptionUtils;
 
/**
 * DSA安全编码组件
 */
public abstract class DSACoder {
 
    public static final String ALGORITHM = "DSA";
 
    /**
     * 默认密钥字节数
     * 
     * <pre>
     * DSA 
     * Default Keysize 1024  
     * Keysize must be a multiple of 64, ranging from 512 to 1024 (inclusive).
     * </pre>
     */
    private static final int KEY_SIZE = 1024;
 
    private static final String PUBLIC_KEY = "DSAPublicKey";
    private static final String PRIVATE_KEY = "DSAPrivateKey";
 
    /**
     * 用私钥对信息生成数字签名
     * 
     * @param data 加密数据
     * @param privateKey 私钥
     * 
     * @return
     */
    public static byte[] sign(byte[] data, byte[] privateKey) {
    	try{
            // 构造PKCS8EncodedKeySpec对象
	        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKey);
	 
            // KEY_ALGORITHM 指定的加密算法
	        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
	 
            // 取私钥匙对象
	        PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
	 
            // 用私钥对信息生成数字签名
	        Signature signature = Signature.getInstance(keyFactory.getAlgorithm());
	        signature.initSign(priKey);
	        signature.update(data);
	 
	        return signature.sign();
    	} catch (GeneralSecurityException e) {
			throw ExceptionUtils.unchecked(e);
		}
    }
 
    /**
     * 校验数字签名
     * 
     * @param data 加密数据
     * @param publicKey 公钥
     * @param sign 数字签名
     * 
     * @return 校验成功返回true 失败返回false
     * 
     */
    public static boolean verify(byte[] data, byte[] publicKey, byte[] sign) {
    	try{
            // 构造X509EncodedKeySpec对象
	        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey);
	 
            // ALGORITHM 指定的加密算法
	        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
	 
            // 取公钥匙对象
	        PublicKey pubKey = keyFactory.generatePublic(keySpec);
	 
	        Signature signature = Signature.getInstance(keyFactory.getAlgorithm());
	        signature.initVerify(pubKey);
	        signature.update(data);
	 
            // 验证签名是否正常
	        return signature.verify(sign);
    	} catch (GeneralSecurityException e) {
			throw ExceptionUtils.unchecked(e);
		}
    }
 
    /**
     * 生成密钥
     * 
     * @return 密钥对象
     */
    public static Map<String, Object> initKey() {
    	try{
	        KeyPairGenerator keygen = KeyPairGenerator.getInstance(ALGORITHM);
	        keygen.initialize(KEY_SIZE);
	 
	        KeyPair keys = keygen.genKeyPair();
	 
	        DSAPublicKey publicKey = (DSAPublicKey) keys.getPublic();
	        DSAPrivateKey privateKey = (DSAPrivateKey) keys.getPrivate();
	 
	        Map<String, Object> map = new HashMap<String, Object>(2);
	        map.put(PUBLIC_KEY, publicKey);
	        map.put(PRIVATE_KEY, privateKey);
	 
	        return map;
    	} catch (GeneralSecurityException e) {
			throw ExceptionUtils.unchecked(e);
		}
    }
 
    /**
     * 取得私钥
     * 
     * @param keyMap
     * @return
     */
    public static byte[] getPrivateKey(Map<String, Object> keyMap) {
        Key key = (Key) keyMap.get(PRIVATE_KEY);
 
        return key.getEncoded();
    }
 
    /**
     * 取得公钥
     * 
     * @param keyMap
     * @return
     */
    public static byte[] getPublicKey(Map<String, Object> keyMap) {
        Key key = (Key) keyMap.get(PUBLIC_KEY);
 
        return key.getEncoded();
    }
    
}
